import type { PiniaPluginContext } from 'pinia';
import { toRaw } from 'vue';

type Options = {
  key?: string;
};
// key 的默认值
const __piniaKey = 'pinia 持久化插件默认 key';

// 将修改后的值存 localstorage
const setStorage = (key: string, value: any) => {
  // 数组和对象需要 JSON.stringify
  // key 可以用户定义 所以需要传对象,PersistencePlugin 就需要函数柯里化
  localStorage.setItem(key, JSON.stringify(value));
};
// localstorage 取值
const getStorage = (key: string) =>
  localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {};

// options 接收 main.ts 中设置的 key
export const PersistencePlugin = (options: Options) => {
  // 函数柯里化 将函数返回给pinia  让pinia  调用 注入 context
  return (context: PiniaPluginContext) => {
    const { store } = context; // 获取所有的 store
    // state 更新的时候存进 localstorage
    // ?? 表达式左侧的值是否为 null 或 undefined，如果是的话就返回右侧的值，否则返回左侧的值
    store.$subscribe(() => {
      setStorage(`${options?.key ?? __piniaKey}-${store.$id}`, toRaw(store.$state));
    });
    // 取数据
    const data = getStorage(`${options?.key ?? __piniaKey}-${store.$id}`);
    // 返回值覆盖pinia 原始值
    return {
      ...data
    };
  };
};
